package com.easybbs.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.easybbs.entity.dto.UserMessageCountDto;
import com.easybbs.entity.enums.*;
import com.easybbs.entity.po.*;
import com.easybbs.entity.query.*;
import com.easybbs.entity.vo.request.UserCenterUpdateUserInfoReqVO;
import com.easybbs.entity.vo.response.UserCenterGetUserInfoRspVO;
import com.easybbs.exception.BusinessException;
import com.easybbs.mappers.*;
import com.easybbs.service.AccountService;
import com.easybbs.utils.FileUtils;
import org.springframework.stereotype.Service;

import com.easybbs.entity.vo.PaginationResultVO;
import com.easybbs.service.UserInfoService;
import com.easybbs.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import static com.easybbs.entity.enums.MessageTypeEnum.SYS;


/**
 * 用户信息 业务接口实现
 */
@Service("userInfoService")
public class UserInfoServiceImpl implements UserInfoService {

	@Resource
	private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

	@Resource
	private ForumArticleMapper<ForumArticle, ForumArticleQuery> forumArticleMapper;

	@Resource
	private LikeRecordMapper<LikeRecord, LikeRecordQuery> likeRecordMapper;

	@Resource
	private FileUtils fileUtils;

	@Resource
	private UserMessageMapper<UserMessage, UserMessageQuery> userMessageMapper;

	@Resource
	private UserIntegralRecordMapper<UserIntegralRecord, UserIntegralRecordQuery> userIntegralRecordMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<UserInfo> findListByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<UserInfo> findListByPage(UserInfoQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<UserInfo> list = this.findListByParam(param);
		PaginationResultVO<UserInfo> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(UserInfo bean) {
		return this.userInfoMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(UserInfo bean, UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.deleteByParam(param);
	}

	/**
	 * 根据UserId获取对象
	 */
	@Override
	public UserInfo getUserInfoByUserId(String userId) {
		return this.userInfoMapper.selectByUserId(userId);
	}

	/**
	 * 根据UserId修改
	 */
	@Override
	public Integer updateUserInfoByUserId(UserInfo bean, String userId) {
		return this.userInfoMapper.updateByUserId(bean, userId);
	}

	/**
	 * 根据UserId删除
	 */
	@Override
	public Integer deleteUserInfoByUserId(String userId) {
		return this.userInfoMapper.deleteByUserId(userId);
	}

	/**
	 * 根据Email获取对象
	 */
	@Override
	public UserInfo getUserInfoByEmail(String email) {
		return this.userInfoMapper.selectByEmail(email);
	}

	/**
	 * 根据Email修改
	 */
	@Override
	public Integer updateUserInfoByEmail(UserInfo bean, String email) {
		return this.userInfoMapper.updateByEmail(bean, email);
	}

	/**
	 * 根据Email删除
	 */
	@Override
	public Integer deleteUserInfoByEmail(String email) {
		return this.userInfoMapper.deleteByEmail(email);
	}

	/**
	 * 根据NickName获取对象
	 */
	@Override
	public UserInfo getUserInfoByNickName(String nickName) {
		return this.userInfoMapper.selectByNickName(nickName);
	}

	/**
	 * 根据NickName修改
	 */
	@Override
	public Integer updateUserInfoByNickName(UserInfo bean, String nickName) {
		return this.userInfoMapper.updateByNickName(bean, nickName);
	}

	/**
	 * 根据NickName删除
	 */
	@Override
	public Integer deleteUserInfoByNickName(String nickName) {
		return this.userInfoMapper.deleteByNickName(nickName);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateUserInfoIntegral(String userId, UserIntegralOperTypeEnum operTypeEnum, UserIntegralChangeTypeEnum changeTypeEnum, Integer integral) {
		integral = changeTypeEnum.getChangeType() * integral;
		if (integral == 0) {
			return;
		}
		UserInfo userInfo = userInfoMapper.selectByUserId(userId);
		if (UserIntegralChangeTypeEnum.REDUCE.getChangeType().equals(changeTypeEnum.getChangeType()) && userInfo.getCurrentIntegral() + integral < 0) {
			integral = changeTypeEnum.getChangeType() * userInfo.getCurrentIntegral();
		}

		UserIntegralRecord record = new UserIntegralRecord();
		record.setUserId(userId);
		record.setOperType(operTypeEnum.getOperType());
		record.setCreateTime(new Date());
		record.setIntegral(integral);
		this.userIntegralRecordMapper.insert(record);

		Integer count = this.userInfoMapper.updateIntegral(userId, integral);
		if (count == 0) {
			throw new BusinessException("更新用户积分失败");
		}
	}

	@Override
	public UserCenterGetUserInfoRspVO getUserInfo(String userId) {
		UserInfo userInfo = userInfoMapper.selectByUserId(userId);

		if (ObjectUtils.isEmpty(userId)) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		UserCenterGetUserInfoRspVO rspVO = UserCenterGetUserInfoRspVO.builder()
				.userId(userInfo.getUserId())
				.nickName(userInfo.getNickName())
				.sex(userInfo.getSex())
				.personDescription(userInfo.getPersonDescription())
				.joinTime(userInfo.getJoinTime())
				.lastLoginTime(userInfo.getLastLoginTime())
				.currentIntegral(userInfo.getCurrentIntegral())
				.build();

		// 文章数量
		ForumArticleQuery articleQuery = new ForumArticleQuery();
		articleQuery.setUserId(userId);
		articleQuery.setStatus(ArticleStatusEnum.AUDIT.getStatus());
		Integer postArticlesCount = forumArticleMapper.selectCount(articleQuery);

		rspVO.setPostCount(postArticlesCount);

		// 点赞数量
		LikeRecordQuery likeRecordQuery = new LikeRecordQuery();
		likeRecordQuery.setUserId(userId);
		likeRecordQuery.setOpType(OperRecordOpTypeEnum.ARTICLE_LIKE.getType());
		Integer likeCount = likeRecordMapper.selectCount(likeRecordQuery);

		rspVO.setLikeCount(likeCount);

		return rspVO;
	}

	@Override
	public void updateUserInfo(UserInfo userInfo, UserCenterUpdateUserInfoReqVO reqVO) {

		UserInfoQuery query = new UserInfoQuery();
		query.setUserId(userInfo.getUserId());
		userInfo.setSex(reqVO.getSex() == null ? userInfo.getSex() : reqVO.getSex());
		userInfo.setPersonDescription(reqVO.getPersonDescription() == null ? userInfo.getPersonDescription() : reqVO.getPersonDescription());
		updateByParam(userInfo, query);

		if (!ObjectUtils.isEmpty(reqVO.getAvatar())) {
			fileUtils.uploadFile2Local(reqVO.getAvatar(), userInfo.getUserId(), FileUploadTypeEnum.AVATAR);
		}

	}

	@Override
	public UserMessageCountDto getMessageCount(String userId) {
		UserMessageCountDto dto = new UserMessageCountDto();
		UserMessageQuery query = new UserMessageQuery();
		query.setReceivedUserId(userId);
//		query.setStatus(MessageStatusEnum.NO_READ.getStatus());
		List<UserMessage> userMessages = userMessageMapper.selectList(query);
		Long total = 0L;
		for (UserMessage userMessage : userMessages) {
			Integer messageType = userMessage.getMessageType();
			MessageTypeEnum messageTypeEnum = MessageTypeEnum.getByType(messageType);

			switch (messageTypeEnum) {
				case SYS:
					dto.setSys(dto.getSys() + 1);
					break;
				case COMMENT:
					dto.setReply(dto.getReply() + 1);
					break;
				case ARTICLE_LIKE:
					dto.setLikePost(dto.getLikePost() + 1);
					break;
				case COMMENT_LIKE:
					dto.setLikeComment(dto.getLikeComment() + 1);
					break;
				case DOWNLOAD_ATTACHMENT:
					dto.setDownloadAttachment(dto.getDownloadAttachment() + 1);
					break;
			}
			total += 1;
		}
		dto.setTotal(total);

		return dto;
	}
}